package rattlesnake.callback.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpContentCompressor;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import rattlesnake.callback.NettyAppcation;
import rattlesnake.callback.server.handler.HttpPrepareServerHandler;


/**
 * @Package: com.example.netty
 * @Description: Netty
 * @author: liuxin
 * @date: 17/4/11 下午1:55
 */
public class NettyServer2 {

    private static final Logger logger = LoggerFactory.getLogger(NettyAppcation.class);

    public static void run(Integer port) {
        ServerBootstrap bootstrap = new ServerBootstrap();
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        bootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
                .localAddress(port).handler(new LoggingHandler(LogLevel.INFO)).childHandler(new ChannelInitializer<Channel>() {
            @Override
            protected void initChannel(Channel channel) throws Exception {
                ChannelPipeline cp = channel.pipeline();
                cp.addLast("decoder", new HttpRequestDecoder());
                cp.addLast("encoder", new HttpResponseEncoder());
                cp.addLast("aggregator", new HttpObjectAggregator(1048576));
                cp.addLast("deflater", new HttpContentCompressor());
                cp.addLast("handler", new HttpPrepareServerHandler());
            }
        }).option(ChannelOption.SO_BACKLOG, 128);
        try {
            ChannelFuture channelFuture = bootstrap.bind().sync();
            showBanner(port);
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException ie) {
            throw new RuntimeException(ie);
        } finally {
            try {
                bossGroup.shutdownGracefully().sync();
                workerGroup.shutdownGracefully().sync();
            } catch (Exception e) {
                throw new RuntimeException("关闭异常", e);
            }
        }
    }


    private static void showBanner(Integer port) {
        logger.info("==========================================================================");
        logger.info("======================NettyAppaction已经启动,端口号:" + port + "====================");
        logger.info("==========================================================================");
    }

    private static class EchoServerHandler extends ChannelInboundHandlerAdapter {
        //用来接收数据
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            System.out.println("Server received: " + msg);
            ctx.write(msg);
        }

        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
            ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            cause.printStackTrace();
            ctx.close();
        }
    }

    private static class EchoServerResponse extends ChannelOutboundHandlerAdapter {
        @Override
        public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
            System.out.println("---输出---");
            ctx.channel().remoteAddress();
            super.write(ctx, msg, promise);
        }
    }
}
